set dylib path correctly for target when running `cargo test` etc
authorJim McGrath <jimmc2@gmail.com>
Fri, 5 May 2017 20:57:47 +0000 (15:57 -0500)
committerJim McGrath <jimmc2@gmail.com>
Mon, 8 May 2017 01:46:05 +0000 (20:46 -0500)
appveyor.yml
src/cargo/ops/cargo_rustc/compilation.rs
src/cargo/ops/cargo_rustc/context.rs
src/cargo/util/rustc.rs
tests/cargotest/lib.rs
tests/cross-compile.rs

index 7c3597b042daf19635cc9f8ed6afa7a786a81925..2ed457233b50b84bb96b0bbbad49110898342a33 100644 (file)
@@ -28,7 +28,11 @@ install:
   - if defined MINGW_URL 7z x -y %MINGW_ARCHIVE% > nul
   - if defined MINGW_URL set PATH=%CD%\%MINGW_DIR%\bin;C:\msys64\usr\bin;%PATH%
 
-  - appveyor-retry appveyor DownloadFile https://win.rustup.rs/ -FileName rustup-init.exe
+  # FIXME(#3394) use master rustup
+  # for the purposes of testing this PR, use rustup 1.2.0 because there is possibly a 
+  # change https://github.com/rust-lang-nursery/rustup.rs/pull/1093 about to land
+  # nightly rustup that will also fix some of the failing windows tests.
+  - curl -sSfO https://static.rust-lang.org/rustup/archive/1.2.0/x86_64-pc-windows-msvc/rustup-init.exe
   - rustup-init.exe -y --default-host x86_64-pc-windows-msvc --default-toolchain nightly-2017-03-03
   - set PATH=%PATH%;C:\Users\appveyor\.cargo\bin
   - if NOT "%TARGET%" == "x86_64-pc-windows-msvc" rustup target add %TARGET%
index 5192d2cadb8a0f894088516c142f6ede42432d9c..cbdb29baa93bd1f5eb92625231582bd5c5b7fb65 100644 (file)
@@ -35,6 +35,12 @@ pub struct Compilation<'cfg> {
     /// which have dynamic dependencies.
     pub plugins_dylib_path: PathBuf,
 
+    /// The path to rustc's own libstd
+    pub host_dylib_path: Option<PathBuf>,
+
+    /// The path to libstd for the target
+    pub target_dylib_path: Option<PathBuf>,
+
     /// Extra environment variables that were passed to compilations and should
     /// be passed to future invocations of programs.
     pub extra_env: HashMap<PackageId, Vec<(String, String)>>,
@@ -57,6 +63,8 @@ impl<'cfg> Compilation<'cfg> {
             root_output: PathBuf::from("/"),
             deps_output: PathBuf::from("/"),
             plugins_dylib_path: PathBuf::from("/"),
+            host_dylib_path: None,
+            target_dylib_path: None,
             tests: Vec::new(),
             binaries: Vec::new(),
             extra_env: HashMap::new(),
@@ -98,7 +106,9 @@ impl<'cfg> Compilation<'cfg> {
                 -> CargoResult<ProcessBuilder> {
 
         let mut search_path = if is_host {
-            vec![self.plugins_dylib_path.clone()]
+            let mut search_path = vec![self.plugins_dylib_path.clone()];
+            search_path.push(self.host_dylib_path.iter().collect());
+            search_path
         } else {
             let mut search_path = vec![];
 
@@ -128,6 +138,7 @@ impl<'cfg> Compilation<'cfg> {
             }
             search_path.push(self.root_output.clone());
             search_path.push(self.deps_output.clone());
+            search_path.push(self.target_dylib_path.iter().collect());
             search_path
         };
 
index 27cd369ba6df1f9a83b993e98bebdbcf82f42281..1310ae189f81e2c8753f5cf3883c20851d04a1d1 100644 (file)
@@ -243,6 +243,24 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
             None
         };
 
+        if let Some(ref sysroot) = self.config.rustc()?.sysroot {
+            let mut rustlib = sysroot.clone();
+            if kind == Kind::Host {
+                if cfg!(windows) {
+                    rustlib.push("bin");
+                } else {
+                    rustlib.push("lib");
+                }
+                self.compilation.host_dylib_path = Some(rustlib);
+            } else {
+                rustlib.push("lib");
+                rustlib.push("rustlib");
+                rustlib.push(self.target_triple());
+                rustlib.push("lib");
+                self.compilation.target_dylib_path = Some(rustlib);
+            }
+        };
+
         let info = match kind {
             Kind::Target => &mut self.target_info,
             Kind::Host => &mut self.host_info,
index d401452d712fee08f0da58cfd4600f3d9387569b..cd2c55104306ad93ee170e45d0c903c887126a04 100644 (file)
@@ -7,6 +7,7 @@ pub struct Rustc {
     pub wrapper: Option<PathBuf>,
     pub verbose_version: String,
     pub host: String,
+    pub sysroot: Option<PathBuf>,
 }
 
 impl Rustc {
@@ -35,11 +36,20 @@ impl Rustc {
             triple.to_string()
         };
 
+        let sysroot = {
+            let mut cmd = util::process(&path);
+            cmd.arg("--print=sysroot");      
+            cmd.exec_with_output().ok()
+                .and_then(|output| String::from_utf8(output.stdout).ok() )
+                .map(|s| PathBuf::from(s.trim()))
+        };
+
         Ok(Rustc {
             path: path,
             wrapper: wrapper,
             verbose_version: verbose_version,
             host: host,
+            sysroot: sysroot
         })
     }
 
index 8446fa829eaa3abdb1bb7e286bd0f33acd473e11..e8497285df13f1f5d5b6bcdd99a60777fe73eb05 100644 (file)
@@ -20,10 +20,9 @@ extern crate url;
 
 use std::ffi::OsStr;
 use std::time::Duration;
-use std::path::{Path, PathBuf};
 
 use cargo::util::Rustc;
-use cargo::util::paths;
+use std::path::PathBuf;
 
 pub mod support;
 pub mod install;
@@ -67,25 +66,6 @@ fn _process(t: &OsStr) -> cargo::util::ProcessBuilder {
      .env_remove("GIT_COMMITTER_EMAIL")
      .env_remove("CARGO_TARGET_DIR")     // we assume 'target'
      .env_remove("MSYSTEM");             // assume cmd.exe everywhere on windows
-
-    // We'll need dynamic libraries at some point in this test suite, so ensure
-    // that the rustc libdir is somewhere in LD_LIBRARY_PATH as appropriate.
-    let mut rustc = RUSTC.with(|r| r.process());
-    let output = rustc.arg("--print").arg("sysroot").exec_with_output().unwrap();
-    let libdir = String::from_utf8(output.stdout).unwrap();
-    let libdir = Path::new(libdir.trim());
-    let libdir = if cfg!(windows) {
-        libdir.join("bin")
-    } else {
-        libdir.join("lib")
-    };
-    let mut paths = paths::dylib_path();
-    println!("libdir: {:?}", libdir);
-    if !paths.contains(&libdir) {
-        paths.push(libdir);
-        p.env(paths::dylib_path_envvar(),
-              paths::join_paths(&paths, paths::dylib_path_envvar()).unwrap());
-    }
     return p
 }
 
index 03dee05491cabb0bebedfb796036535671068d08..d4c134fc3e054dff3f2befb723e8d596c95f0a30 100644 (file)
@@ -1053,3 +1053,79 @@ fn platform_specific_variables_reflected_in_build_scripts() {
     assert_that(p.cargo("build").arg("-v").arg("--target").arg(&target),
                 execs().with_status(0));
 }
+
+#[test]
+fn cross_test_dylib() {
+    if disabled() { return }
+
+    let target = alternate();
+
+    let p = project("foo")
+        .file("Cargo.toml", r#"
+            [package]
+            name = "foo"
+            version = "0.0.1"
+            authors = []
+
+            [lib]
+            name = "foo"
+            crate_type = ["dylib"]
+
+            [dependencies.bar]
+            path = "bar"
+        "#)
+        .file("src/lib.rs", r#"
+            extern crate bar as the_bar;
+
+            pub fn bar() { the_bar::baz(); }
+
+            #[test]
+            fn foo() { bar(); }
+        "#)
+        .file("tests/test.rs", r#"
+            extern crate foo as the_foo;
+
+            #[test]
+            fn foo() { the_foo::bar(); }
+        "#)
+        .file("bar/Cargo.toml", r#"
+            [package]
+            name = "bar"
+            version = "0.0.1"
+            authors = []
+
+            [lib]
+            name = "bar"
+            crate_type = ["dylib"]
+        "#)
+        .file("bar/src/lib.rs", &format!(r#"
+             use std::env;
+             pub fn baz() {{
+                assert_eq!(env::consts::ARCH, "{}");
+            }}
+        "#, alternate_arch()));
+
+    assert_that(p.cargo_process("test").arg("--target").arg(&target),
+                execs().with_status(0)
+                       .with_stderr(&format!("\
+[COMPILING] bar v0.0.1 ({dir}/bar)
+[COMPILING] foo v0.0.1 ({dir})
+[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
+[RUNNING] target[/]{arch}[/]debug[/]deps[/]foo-[..][EXE]
+[RUNNING] target[/]{arch}[/]debug[/]deps[/]test-[..][EXE]",
+                        dir = p.url(), arch = alternate()))
+                       .with_stdout("
+running 1 test
+test foo ... ok
+
+test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
+
+
+running 1 test
+test foo ... ok
+
+test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
+
+"));
+
+}